import 'package:flutter/material.dart';

import '../../../resources/l10n/kq_core_s.dart';
import '../../gesture/kq_gesture_detector.dart';

abstract class BaseChartDelegate<D> {
  BaseChartDelegate(
      {this.animDuration,
      this.data,
      this.gestureHandler,
      this.emptyWidgetBuilder,
      this.isDataEmpty});

  /// 动画时间，设置此值则启用动画绘制
  final Duration? animDuration;

  final D? data;

  final bool Function(D? data)? isDataEmpty;

  /// 当[isEmptyData]返回true时显示的内容
  final Widget Function()? emptyWidgetBuilder;

  final BaseChartGestureHandlerMixin? gestureHandler;

  KqChartState? _chartState;

  /// 图表关联的[State]
  KqChartState? get chartState => _chartState;

  Size _size = Size.zero;

  /// 图表组件占用大小
  Size get size => _size;

  bool get isEmptyData;

  void onDraw(Canvas canvas, double animProgress);

  /// 关联上Chart，此时[State.initState]已执行
  @mustCallSuper
  void attachChart(KqChartState state) {
    _chartState = state;
    gestureHandler?.attachChart(this);
  }

  @mustCallSuper
  void didUpdateWidget(covariant BaseChart oldWidget) {}

  /// 界面销毁
  @mustCallSuper
  void dispose() {
    _chartState = null;
    gestureHandler?.dispose();
  }

  /// 刷新界面数据
  void update() {
    _chartState?.update();
  }
}

/// 手势事件处理
mixin BaseChartGestureHandlerMixin<C extends BaseChartDelegate> {
  void attachChart(C delegate);

  void dispose();

  /// 拖拽开始，此事件发生在手指按下首次滑动
  void onDragStart(DragStartDetails details);

  /// 拖拽按下，此事件发生在手指首次触摸屏幕
  void onDragDown(DragDownDetails details);

  /// 拖拽更新，此事件发生在手指持续滑动过程
  void onDragUpdate(DragUpdateDetails details);

  /// 拖拽结束，此事件发生在手指持续滑动后抬起
  void onDragEnd(DragEndDetails details);

  /// 拖拽取消，此事件发生在手指按下但未发生任何滑动时执行
  /// 可表示单次点击事件
  void onDragCancel();
}

/// 图表
class BaseChart extends StatefulWidget {
  const BaseChart({super.key, required this.delegate});

  final BaseChartDelegate delegate;

  @override
  State<StatefulWidget> createState() => KqChartState();
}

/// 科强表格[State]基类
class KqChartState extends State<BaseChart> with TickerProviderStateMixin {
  /// 控制绘制动画
  AnimationController? _animationController;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(vsync: this);
    widget.delegate.attachChart(this);
  }

  @override
  void dispose() {
    _animationController?.dispose();
    widget.delegate.dispose();
    super.dispose();
  }

  @override
  void didUpdateWidget(covariant BaseChart oldWidget) {
    super.didUpdateWidget(oldWidget);
    widget.delegate.attachChart(this);
    widget.delegate.didUpdateWidget(oldWidget);
  }

  @override
  Widget build(BuildContext context) {
    _animationController?.stop(canceled: true);
    var builder = widget.delegate.emptyWidgetBuilder;
    if (widget.delegate.isEmptyData && builder != null) {
      return builder.call();
    }

    var gestureHandler = widget.delegate.gestureHandler;
    if (gestureHandler == null) {
      return SizedBox.expand(
        child: _buildContent(context),
      );
    }

    return KqGestureDetector(
      onDragDown: gestureHandler.onDragDown,
      onDragStart: gestureHandler.onDragStart,
      onDragUpdate: gestureHandler.onDragUpdate,
      onDragEnd: gestureHandler.onDragEnd,
      onDragCancel: gestureHandler.onDragCancel,
      child: SizedBox.expand(
        child: _buildContent(context),
      ),
    );
  }

  Widget _buildContent(BuildContext context) {
    return widget.delegate.animDuration == null || widget.delegate.isEmptyData
        ? buildChild(context, 1)
        : _withAnim(widget.delegate.animDuration!);
  }

  Widget _withAnim(Duration duration) {
    _animationController?.duration = duration;
    var widget = AnimatedBuilder(
      animation: _animationController!,
      builder: (context, child) {
        return buildChild(context, _animationController?.value ?? 1);
      },
    );
    _animationController?.forward();
    return widget;
  }

  @protected
  Widget buildChild(BuildContext context, double animProgress) {
    return CustomPaint(
        painter: _ChartPainter(state: this, animProgress: animProgress));
  }

  void update() {
    setState(() {});
  }
}

/// 图表绘制器
class _ChartPainter extends CustomPainter {
  const _ChartPainter({required this.state, this.animProgress = 1})
      : assert(animProgress >= 0 && animProgress <= 1);

  /// 绘制器所依赖的饼状图[KqBasePieChartState]
  final KqChartState state;

  /// 动画进度，用于根据动画进行进行绘制
  final double animProgress;

  @override
  void paint(Canvas canvas, Size size) {
    state.widget.delegate._size = size;
    if (size.isEmpty) {
      return;
    }

    state.widget.delegate.onDraw(canvas, animProgress);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

/// 获取默认的空数据界面
Widget getDefEmptyView(
        {double fontSize = 12, Color color = Colors.black}) =>
    Align(
      alignment: Alignment.center,
      child: Text(
        KqCoreS.currentResource.noDataTip,
        style: TextStyle(fontSize: fontSize, color: color),
      ),
    );
